﻿/**
 *	\file		vec.hpp
 *	\date		(2006-06-19 23:34:16)/(2015-02-01 23:55:26)
 *-----------------------------------------------------------------------------
 *	\brief		向量.
 *	\version	1.0.22.31
 *	\author		Nick Shallery	(nicknide@gmail.com)
 *	\copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/

#if			!defined(__LOLIX__SOLA__VEC__NICK__K_IN_G__)
#define		__LOLIX__SOLA__VEC__NICK__K_IN_G__
#ifdef		__cplusplus

#if			!defined(__LOLIX__SOLA__CALC__H__NICK__K_IN_G__)
	#include	"./calc.h"
#endif	//	!defined(__LOLIX__SOLA__CALC__H__NICK__K_IN_G__)

#if			!defined(__LOLIX__LOLI_X_CFG__K_IN_G__)
	#include	"../lolix_cfg.h"
#endif	//	!defined(__LOLIX__LOLI_X_CFG__K_IN_G__)

#if			!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
	#include	"../lolix_type.h"
#endif	//	!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)

#if			!defined(__LOLIX__TOY__ALIGN__HPP__NICK__K_IN_G__)
	#include	"../toy/align.hpp"
#endif	//	!defined(__LOLIX__TOY__ALIGN__HPP__NICK__K_IN_G__)

namespace lolix{namespace sola{
	namespace _help
	{
		template<size_type dim, typename v_type>
		class vec_base
		{
		public:
			enum { dim_value = dim };
			typedef v_type value_type;

#if			LOLIX_CFG__IS_DEBUG
		protected:
			LOLIX_INLINE_CALL vec_base(void){}
#endif	//	LOLIX_CFG__IS_DEBUG
		};

		template<unsigned int dim, typename v_type>
		class matrix_base
		{
		public:
			enum { dim_value = dim };
			typedef v_type value_type;

#if			LOLIX_CFG__IS_DEBUG
		protected:
			LOLIX_INLINE_CALL matrix_base(void){}
#endif	//	LOLIX_CFG__IS_DEBUG
		};
	}
	template <size_type dim, typename value_type = float>class vec;
	template <size_type dim, typename value_type = float>class matrix;
}}


namespace lolix{namespace sola{
template<typename v_type>
class vec<1, v_type>
	: public _help::vec_base<1, v_type>
{
	typedef vec<1, v_type>		this_type;
	typedef this_type&			this_ref;
	typedef	const	this_type&	this_const_ref;
public:
	LOLIX_INLINE_CALL vec(void)
	{ ; }
	LOLIX_INLINE_CALL vec(v_type in_x): x(in_x){}

	LOLIX_INLINE_CALL this_ref operator += (const this_type o){ x += o.x; return *this; }
	LOLIX_INLINE_CALL this_ref operator -= (const this_type o){ x -= o.x; return *this; }
	LOLIX_INLINE_CALL this_type operator - (void)const{ return this_type(x*v_type(-1)); }
	LOLIX_INLINE_CALL const v_type dot(const this_type o)const{ return x*o.x; }
	LOLIX_INLINE_CALL this_ref operator*=(const matrix<1, v_type> mat)
	{
		x = this->dot(mat.x);
		return *this;
	}

	LOLIX_INLINE_CALL this_ref operator *= (v_type o){ x *= o; return *this; }
	LOLIX_INLINE_CALL this_ref operator /= (v_type o){ x /= o; return *this; }
	LOLIX_INLINE_CALL this_ref operator *= (this_const_ref o){ x *= o.x; return *this; }
	LOLIX_INLINE_CALL this_ref operator /= (this_const_ref o){ x /= o/x; return *this; }
	LOLIX_INLINE_CALL bool operator == (this_const_ref o)const{return this->x == o.x;}
	LOLIX_INLINE_CALL bool operator != (this_const_ref o)const{return this->x != o.x;}

	LOLIX_INLINE_CALL this_type normalize(void)const{return this_type(v_type(1));}
	LOLIX_INLINE_CALL this_ref normalize_self(void){x = v_type(1);return *this;}
	template<typename size_type>
	LOLIX_INLINE_CALL v_type& operator[](size_type idx){return *(&x + idx);}
	template<typename size_type>
	LOLIX_INLINE_CALL v_type operator[](size_type idx)const{return *(&x + idx);}

	v_type x;
};
}}


namespace lolix{namespace sola{
template<typename v_type>
class vec<2, v_type>
	: public _help::vec_base<2, v_type>
{
	typedef vec<2, v_type>		this_type;
	typedef this_type&			this_ref;
	typedef const this_type&	this_const_ref;
public:
	LOLIX_INLINE_CALL vec(void){ ; }
	LOLIX_INLINE_CALL vec(v_type in_x, v_type in_y): x(in_x), y(in_y){}
	template<typename _T0, typename _T1>
	LOLIX_INLINE_CALL vec(vec<1, _T0> t0, vec<1, _T1> t1): x(t0.x), y(t1.x){}
	template<typename _T0, typename _T1>
	LOLIX_INLINE_CALL vec(vec<1, _T0> t0, _T1 t1): x(t0.x), y(t1){}
	template<typename _T0, typename _T1>
	LOLIX_INLINE_CALL vec(_T0 t0, vec<1, _T1> t1): x(t0), y(t1.x){}
	template<typename _T0>
	LOLIX_INLINE_CALL vec(vec<2, _T0> t0): x(t0.x), y(t0.y){}

	LOLIX_INLINE_CALL this_ref operator += (this_const_ref v)
	{
		x += v.x;
		y += v.y;
		return *this;
	}
	LOLIX_INLINE_CALL const this_type operator + (this_const_ref v)const
	{
		this_type tmp(*this);
		return tmp += v;
	}

	LOLIX_INLINE_CALL this_ref operator -= (this_const_ref v)
	{
		x -= v.x;
		y -= v.y;
		return *this;
	}
	LOLIX_INLINE_CALL const this_type operator - (this_const_ref v)const
	{
		this_type tmp(*this);
		return tmp -= v;
	}
	LOLIX_INLINE_CALL const this_type operator - (void)const
	{
		this_type tmp;
		const v_type v(-1);
		tmp[0] = x*v;
		tmp[1] = y*v;
		return tmp;
	}
	LOLIX_INLINE_CALL v_type dot(this_const_ref o)const
	{
		v_type tmp = 0.f;
		tmp+=x*o.x;
		tmp+=y*o.y;

		return tmp;
	}


	template <typename size_type>
	LOLIX_INLINE_CALL v_type& operator[](size_type index){ return reinterpret_cast<v_type*>(this)[index]; }
	template <typename size_type>
	LOLIX_INLINE_CALL const v_type operator[](size_type index)const{ return const_cast<this_type&>(*this)[index]; }
	LOLIX_INLINE_CALL void operator()(v_type v0, v_type v1){this->x = v0; this->y = v1;}
	LOLIX_INLINE_CALL this_ref operator*=(const matrix<2, v_type>& mat)
	{
		this_type tmp;
		tmp[0] = this->dot(mat.x);
		tmp[1] = this->dot(mat.y);
		return *this = tmp;
	}

	LOLIX_INLINE_CALL this_ref operator *= (v_type v)
	{
		x *= v;
		y *= v;
		return *this;
	}

	LOLIX_INLINE_CALL this_ref operator /= (v_type v){return (*this)*= v_type(1)/v;}
	LOLIX_INLINE_CALL this_ref operator *= (this_const_ref o)
	{
		x *= o.x;
		y *= o.y;
		return *this;
	}

	LOLIX_INLINE_CALL this_ref operator /= (this_const_ref o)
	{
		x /= o.x;
		y /= o.y;
		return *this;
	}

	LOLIX_INLINE_CALL const this_type operator *(v_type v)const
	{
		this_type tmp(*this);
		tmp*=v;
		return tmp;
	}

	LOLIX_INLINE_CALL const this_type operator /(v_type v)const
	{
		this_type tmp(*this);
		tmp/=v;
		return tmp;
	}

	LOLIX_INLINE_CALL const this_type operator *(this_const_ref o)const
	{
		this_type tmp(*this);
		return tmp*=o;
	}

	LOLIX_INLINE_CALL const this_type operator /(this_const_ref o)const
	{
		this_type tmp(*this);
		return tmp/=o;
	}

	LOLIX_INLINE_CALL bool operator == (this_const_ref o)const{return this->x == o.x && this->y == o.y;}
	LOLIX_INLINE_CALL bool operator != (this_const_ref o)const{return this->x != o.x || this->y != o.y;}

	LOLIX_INLINE_CALL this_type normalize(void)const
	{
		const v_type tmp = v_type(1)/size();
		return this_type(x*tmp, y*tmp);
	}

	LOLIX_INLINE_CALL this_ref normalize_self(void)
	{
		const v_type tmp = v_type(1)/size();
		x *= tmp;
		y *= tmp;
		return *this;
	}

	LOLIX_INLINE_CALL v_type size(void)const{return calc_sqrt<v_type>::invoke(size_p2());}
	LOLIX_INLINE_CALL v_type size_p2(void)const{return x*x + y*y;}

	v_type x;
	v_type y;
};
}}


namespace lolix{namespace sola{
template<typename v_type>
class vec<3, v_type>
	: public _help::vec_base<3, v_type>
{
	typedef vec<3, v_type>		this_type;
	typedef this_type&			this_ref;
	typedef const this_type&	this_const_ref;
public:
	LOLIX_INLINE_CALL vec(void){ ; }
	LOLIX_INLINE_CALL vec(v_type in_x, v_type in_y, v_type in_z): x(in_x), y(in_y), z(in_z){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(vec<1, _T0> t0, vec<1, _T1> t1, vec<1, _T2> t2): x(t0.x), y(t1.x), z(t1.x){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(_T0 t0, vec<1, _T1> t1, vec<1, _T2> t2): x(t0), y(t1.x), z(t1.x){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(vec<1, _T0> t0, _T1 t1, vec<1, _T2> t2): x(t0.x), y(t1), z(t1.x){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(vec<1, _T0> t0, vec<1, _T1> t1, _T2 t2): x(t0.x), y(t1.x), z(t1){}

	template<typename _T0, typename _T1>
	LOLIX_INLINE_CALL vec(vec<1, _T0> t0, vec<2, _T1> t1): x(t0.x), y(t1.x), z(t1.y){}
	template<typename _T0, typename _T1>
	LOLIX_INLINE_CALL vec(_T0 t0, vec<2, _T1> t1): x(t0), y(t1.x), z(t1.y){}
	template<typename _T0, typename _T1>
	LOLIX_INLINE_CALL vec(vec<2, _T0> t0, vec<1, _T1> t1): x(t0.x), y(t0.y), z(t1.x){}
	template<typename _T0, typename _T1>
	LOLIX_INLINE_CALL vec(vec<2, _T0> t0, _T1 t1): x(t0.x), y(t0.y), z(t1){}
	template<typename _T0>
	LOLIX_INLINE_CALL vec(vec<3, _T0> t0): x(t0.x), y(t0.y), z(t0.z){}

	LOLIX_INLINE_CALL this_ref operator += (this_const_ref v)
	{
		x += v.x;
		y += v.y;
		z += v.z;
		return *this;
	}
	LOLIX_INLINE_CALL const this_type operator + (this_const_ref v)const
	{
		this_type tmp(*this);
		return tmp+=v;
	}

	LOLIX_INLINE_CALL this_ref operator -= (this_const_ref v)
	{
		x -= v.x;
		y -= v.y;
		z -= v.z;
		return *this;
	}

	LOLIX_INLINE_CALL const this_type operator - (this_const_ref v)const
	{
		this_type tmp(*this);
		return tmp -= v;
	}

	LOLIX_INLINE_CALL const this_type operator - (void)const
	{
		this_type tmp;
		const v_type v(-1);
		tmp[0] = x*v;
		tmp[1] = y*v;
		tmp[2] = z*v;
		return tmp;
	}

	LOLIX_INLINE_CALL v_type dot(this_const_ref o)const
	{
		v_type tmp(x*o.x);
		tmp+=y*o.y;
		tmp+=z*o.z;
		return tmp;
	}

	template <typename size_type>
	LOLIX_INLINE_CALL v_type& operator[](size_type index){ return reinterpret_cast<v_type*>(this)[index]; }
	template <typename size_type>
	LOLIX_INLINE_CALL const v_type operator[](size_type index)const{ return const_cast<this_type&>(*this)[index]; }
	LOLIX_INLINE_CALL void operator()(v_type v0, v_type v1, v_type v3){this->x = v0; this->y = v1; this->z = v3;}
	LOLIX_INLINE_CALL this_ref operator*=(const matrix<3, v_type>& mat)
	{
		this_type tmp;
		tmp[0] = this->dot(mat.x);
		tmp[1] = this->dot(mat.y);
		tmp[2] = this->dot(mat.z);
		return *this = tmp;
	}

	LOLIX_INLINE_CALL this_ref operator *= (v_type v)
	{
		x *= v;
		y *= v;
		z *= v;
		return *this;
	}

	LOLIX_INLINE_CALL this_ref operator *= (this_const_ref o)
	{
		x *= o.x;
		y *= o.y;
		z *= o.z;
		return *this;
	}

	LOLIX_INLINE_CALL this_ref operator /= (this_const_ref o)
	{
		x /= o.x;
		y /= o.y;
		z /= o.z;
		return *this;
	}

	LOLIX_INLINE_CALL this_ref operator /= (v_type v)
	{
		v = v_type(1)/v;
		return (*this)*=v;
	}

	LOLIX_INLINE_CALL const this_type operator / (v_type v)const
	{
		this_type tmp(*this);
		return tmp /= v;
	}

	LOLIX_INLINE_CALL const this_type operator *(v_type v)const
	{
		this_type tmp(*this);
		tmp*=v;
		return tmp;
	}

	LOLIX_INLINE_CALL const this_type operator * (this_const_ref o)const
	{
		this_type tmp(*this);
		return tmp*=o;
	}

	LOLIX_INLINE_CALL bool operator == (this_const_ref o)const{return this->x == o.x && this->y == o.y && this->z == o.z;}
	LOLIX_INLINE_CALL bool operator != (this_const_ref o)const{return this->x != o.x || this->y != o.y || this->z != o.z;}

	LOLIX_INLINE_CALL const this_type cross(this_const_ref o)const
	{
		this_type tmp;
		tmp[0] = y*o[2] - z*o[1];
		tmp[1] = z*o[0] - x*o[2];
		tmp[2] = x*o[1] - y*o[0];
		return tmp;
	}

	LOLIX_INLINE_CALL this_ref cross_to(this_const_ref o)
	{
		this_type tmp(*this);
		x = tmp[1]*o[2] - tmp[2]*o[1];
		y = tmp[2]*o[0] - tmp[0]*o[2];
		z = tmp[0]*o[1] - tmp[1]*o[0];
		return *this;
	}

	LOLIX_INLINE_CALL this_type normalize(void)const
	{
		v_type tmp = v_type(1)/size();
		return this_type(x*tmp, y*tmp, z*tmp);
	}

	LOLIX_INLINE_CALL this_ref normalize_self(void)
	{
		v_type tmp = v_type(1)/size();

		x *= tmp;
		y *= tmp;
		z *= tmp;

		return *this;
	}

	LOLIX_INLINE_CALL v_type size(void)const{return calc_sqrt<v_type>::invoke(size_p2());}
	LOLIX_INLINE_CALL v_type size_p2(void)const{return x*x + y*y + z*z;}

	v_type x;
	v_type y;
	v_type z;
};
}}


namespace lolix{namespace sola{
template<typename v_type>
class vec<4, v_type>
	: public _help::vec_base<4, v_type>
{
	typedef vec<4, v_type>		this_type;
	typedef this_type&			this_ref;
	typedef const this_type&	this_const_ref;
public:
	LOLIX_INLINE_CALL vec(void){ ; }
	LOLIX_INLINE_CALL vec(v_type in_x, v_type in_y, v_type in_z): x(in_x), y(in_y), z(in_z), w(1){}
	LOLIX_INLINE_CALL vec(v_type in_x, v_type in_y, v_type in_z, v_type in_w): x(in_x), y(in_y), z(in_z), w(in_w){}

	template<typename _T0, typename _T1, typename _T2, typename _T3>
	LOLIX_INLINE_CALL vec(vec<1, _T0> t0, vec<1, _T1> t1, vec<1, _T2> t2, vec<1, _T3> t3): x(t0.x), y(t1.x), z(t1.x), w(t2.x){}

	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(vec<2, _T0> const& t0, vec<1, _T1> t1, vec<1, _T2> t2): x(t0.x), y(t0.y), z(t1.x), w(t2.x){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(vec<2, _T0> const& t0, _T1 t1, vec<1, _T2> t2): x(t0.x), y(t0.y), z(t1), w(t2.x){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(vec<2, _T0> const& t0, vec<1, _T1> t1, _T2 t2): x(t0.x), y(t0.y), z(t1.x), w(t2){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(vec<2, _T0> const& t0, _T1 t1, _T2 t2): x(t0.x), y(t0.y), z(t1), w(t2){}

	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(vec<1, _T0> t0, vec<2, _T1> const& t1, vec<1, _T2> t2): x(t0.x), y(t1.x), z(t1.y), w(t2.x){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(_T0 t0, vec<2, _T1> const& t1, vec<1, _T2> t2): x(t0), y(t1.x), z(t1.y), w(t2.x){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(vec<1, _T0> t0, vec<2, _T1> const& t1, _T2 t2): x(t0.x), y(t1.x), z(t1.y), w(t2){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(_T0 t0, vec<2, _T1> const& t1, _T2 t2): x(t0), y(t1.x), z(t1.y), w(t2){}

	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(vec<1, _T0> t0, vec<1, _T1> t1, vec<2, _T2> const& t2): x(t0.x), y(t1.x), z(t2.x), w(t2.y){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(_T0 t0, vec<1, _T1> t1, vec<2, _T2> const& t2): x(t0), y(t1.x), z(t2.x), w(t2.y){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(vec<1, _T0> t0, _T1 t1, vec<2, _T2> const& t2): x(t0.x), y(t1), z(t2.x), w(t2.y){}
	template<typename _T0, typename _T1, typename _T2>
	LOLIX_INLINE_CALL vec(_T0 t0, _T1 t1, vec<2, _T2> const& t2): x(t0), y(t1), z(t2.x), w(t2.y){}

	template<typename _T0, typename _T1>
	LOLIX_INLINE_CALL vec(vec<2, _T0> const& t0, vec<2, _T1> const& t1): x(t0.x), y(t0.y), z(t1.x), w(t1.y){}

	template<typename _T0, typename _T1>
	LOLIX_INLINE_CALL vec(vec<3, _T0> const& t0, vec<1, _T1> t1): x(t0.x), y(t0.y), z(t0.z), w(t1.x){}
	template<typename _T0, typename _T1>
	LOLIX_INLINE_CALL vec(vec<3, _T0> const& t0, _T1 t1): x(t0.x), y(t0.y), z(t0.z), w(t1){}
	template<typename _T0, typename _T1>
	LOLIX_INLINE_CALL vec(vec<1, _T0> t0, vec<3, _T1> const& t1): x(t0.x), y(t1.x), z(t1.y), w(t1.z){}
	template<typename _T0, typename _T1>
	LOLIX_INLINE_CALL vec(_T0 t0, vec<3, _T1> const& t1): x(t0), y(t1.x), z(t1.y), w(t1.z){}

	template<typename _T0>
	LOLIX_INLINE_CALL vec(vec<4, _T0> const& t0): x(t0.x), y(t0.y), z(t0.z), w(t0.w){}

	LOLIX_INLINE_CALL this_ref operator += (this_const_ref v)
	{
		x += v.x;
		y += v.y;
		z += v.z;
		w += v.w;
		return *this;
	}

	LOLIX_INLINE_CALL this_type operator - (const this_type& o)const
	{
		this_type tmp(*this);
		return tmp-=o;
	}

	LOLIX_INLINE_CALL this_ref operator -= (this_const_ref v)
	{
		x -= v.x;
		y -= v.y;
		z -= v.z;
		w -= v.w;
		return *this;
	}
	LOLIX_INLINE_CALL this_type operator - (void)const
	{
		this_type tmp;
		tmp[0] = -x;
		tmp[1] = -y;
		tmp[2] = -z;
		tmp[3] = -w;
		return tmp;
	}

	LOLIX_INLINE_CALL v_type dot(this_const_ref o)
	{
		v_type tmp = 0.f;
		tmp+=x*o.x;
		tmp+=y*o.y;
		tmp+=z*o.z;
		tmp+=w*o.w;

		return tmp;
	}


	template <typename size_type>
	LOLIX_INLINE_CALL v_type& operator[](size_type index){ return reinterpret_cast<v_type*>(this)[index]; }
	template <typename size_type>
	LOLIX_INLINE_CALL const v_type operator[](size_type index)const{ return const_cast<this_type&>(*this)[index]; }
	LOLIX_INLINE_CALL void operator()(v_type v0, v_type v1, v_type v3){this->x = v0; this->y = v1; this->z = v3;}
	LOLIX_INLINE_CALL void operator()(v_type v0, v_type v1, v_type v3, v_type v4){this->x = v0; this->y = v1; this->z = v3; this->w = v4;}
	LOLIX_INLINE_CALL this_ref operator*=(const matrix<4, v_type>& mat)
	{
		this_type tmp;
		tmp[0] = this->dot(mat[0]);
		tmp[1] = this->dot(mat[1]);
		tmp[2] = this->dot(mat[2]);
		tmp[3] = this->dot(mat[3]);
		return *this = tmp;
	}

	LOLIX_INLINE_CALL this_ref operator *= (v_type v)
	{
		x *= v;
		y *= v;
		z *= v;
		w *= v;
		return *this;
	}

	LOLIX_INLINE_CALL this_ref operator *= (this_const_ref o)
	{
		x *= o.x;
		y *= o.y;
		z *= o.z;
		w *= o.w;
		return *this;
	}

	LOLIX_INLINE_CALL const this_type operator * (const matrix<4, v_type>&mat)const
	{
		this_type t(*this);
		return t*=mat;
	}

	LOLIX_INLINE_CALL const this_type operator * (this_const_ref o)
	{
		this_type tmp(*this);
		return tmp *= o;
	}

	LOLIX_INLINE_CALL bool operator == (this_const_ref o)const{return this->x == o.x && this->y == o.y && this->z == o.z && this->w == o.w;}
	LOLIX_INLINE_CALL bool operator != (this_const_ref o)const{return this->x != o.x || this->y != o.y || this->z != o.z || this->w != o.w;}

	LOLIX_INLINE_CALL this_type normalize(void)const
	{
		const v_type tmp = v_type(1)/size();
		return this_type(x*tmp, y*tmp, z*tmp, w*tmp);
	}

	LOLIX_INLINE_CALL this_ref normalize_self(void)
	{
		const v_type tmp = v_type(1)/size();

		x *= tmp;
		y *= tmp;
		z *= tmp;
		w *= tmp;

		return *this;
	}

	LOLIX_INLINE_CALL const v_type size_p2(void)const{return x*x + y*y + z*z + w*w;}
	LOLIX_INLINE_CALL const v_type size(void)const{return calc_sqrt<v_type>::invoke(size_p2());}

	v_type x;
	v_type y;
	v_type z;
	v_type w;
};
}}

namespace lolix{namespace sola{

	typedef vec<2, lolix::lx_f32>	vec2;
	typedef vec<3, lolix::lx_f32>	vec3;
	typedef vec<4, lolix::lx_f32>	vec4;

	typedef	vec<2, lolix::lx_f64>	dvec2;
	typedef	vec<3, lolix::lx_f64>	dvec3;
	typedef	vec<4, lolix::lx_f64>	dvec4;

	typedef	vec<2, lolix::lx_i32>		ivec2;
	typedef	vec<3, lolix::lx_i32>		ivec3;
	typedef	vec<4, lolix::lx_i32>		ivec4;

	vec3 operator /(vec3::value_type v, vec3 const& t);
	template<size_t _VDim, typename _Tval>
	inline vec3 operator *(typename vec<_VDim, _Tval>::value_type v, vec<_VDim, _Tval> const& t){return t*v;}
}}




#else	//	__cplusplus
#	error	Must Have C++ Complier Support
#endif	//	__cplusplus

#endif	//	!defined(__LOLIX__SOLA__VEC__NICK__K_IN_G__)
